home *** CD-ROM | disk | FTP | other *** search
/ Amiga Game-Power / Amiga Game-Power.iso / pd mix ii / access / hddriver / support / initiate.c < prev    next >
C/C++ Source or Header  |  1994-05-20  |  12KB  |  489 lines

  1.  
  2. #include <stdio.h>
  3. #include "hd.h"
  4.  
  5.  
  6. char rbuf[ HD_SECTOR ];
  7. char wbuf[ HD_SECTOR ];
  8. FILE *input;
  9. FILE *logfile;
  10.  
  11.  
  12. main ( argc , argv )
  13. int argc;
  14. char **argv;
  15. {
  16.     char *commands;
  17.     int done_write;
  18.     int status;
  19.  
  20.  
  21.     if ( argc != 3  &&  argc != 4 )
  22.         usage ();
  23.  
  24.     if ( argc > 3 ) {
  25.         input = fopen ( argv[3] , "r" );
  26.         if ( input == NULL ) {
  27.             fprintf ( stderr , "Failed to open '%s'\n" );
  28.             usage ();
  29.         }
  30.     }
  31.     else
  32.         input = NULL;
  33.  
  34.     logfile = fopen ( argv[1] , "w" );
  35.     if ( logfile == NULL ) {
  36.         printf ( "Failed to create logfile %s\n" , argv[1] );
  37.         usage ();
  38.     }
  39.  
  40.     init_wbuf ();
  41.  
  42.     status = wd_open ();
  43.     if ( status != 0 ) {
  44.         fprintf ( stderr , "wd_open() failed - returned %d\n" , status );
  45.         fprintf ( stderr , "continue(y/n)? " );
  46.         if ( getchar () != 'y' ) {
  47.             wd_close ();
  48.             exit ( 1 );
  49.         }
  50.     }
  51.  
  52.     commands = argv[2];
  53.  
  54.     if ( *commands == 'f'  ||  *commands == 'F' ) {
  55.         if ( input == NULL ) {
  56.             fprintf ( stderr , "Inputfile must be specified when formatting a disk\n" );
  57.             usage ();
  58.         }
  59.         printf ( "Formatting disk\n" );
  60.         fprintf ( logfile , "Formatting disk\n" );
  61.         init_first_sector ();
  62.         format_disk ();
  63.         commands++;
  64.     }
  65.     else {
  66.         if ( input != NULL )
  67.             fprintf ( stderr , "warning: inputfile only used when disk is reformatted\n" );
  68.         read_first_sector ();
  69.         if ( first.magic != HD_MAGIC ) {
  70.             fprintf ( stderr , "incorrect magic number in sector\n" );
  71.             wd_close ();
  72.             exit ( 1 );
  73.         }
  74.     }
  75.  
  76.     done_write = 0;
  77.  
  78.     while ( *commands != '\0' ) {
  79.         switch ( *commands++ ) {
  80.  
  81.         case 'r' :
  82.         case 'R' :
  83.             printf ( "Reading disk\n" );
  84.             fprintf ( logfile , "Reading disk\n" );
  85.             read_disk ( done_write );
  86.             break;
  87.  
  88.         case 'w' :
  89.         case 'W' :
  90.             printf ( "Writing disk\n" );
  91.             fprintf ( logfile , "Pass 3: Writing disk\n" );
  92.             write_disk ();
  93.             done_write = 1;
  94.             break;
  95.  
  96.         default :
  97.             usage ();
  98.         }
  99.     }
  100.  
  101.     printf ( "Done - writing bad sector table to disk\n" );
  102.     dump_first_sector ();
  103.     printf ( "\n%d sectors used for map information\n" , HD_MAP_SECTORS );
  104.     printf ( "%ld sectors used so far for relinking bad sectors\n" ,
  105.         (long)first.bad_sectors );
  106.     printf ( "%ld tracks would be required to hold these sectors\n\n" ,
  107.         (long)( HD_MAP_SECTORS + first.bad_sectors - 1 ) / first.sectors + 1 );
  108.     printf ( "A total of %d sectors could be used for relinking bad sectors\n" ,
  109.         HD_MAP_SECTORS + HD_MAP_SIZE );
  110.     printf ( "This would require %ld reserved tracks\n" ,
  111.         (long) ( HD_MAP_SECTORS + HD_MAP_SIZE - 1 ) / first.sectors + 1 );
  112.  
  113.     fclose ( logfile );
  114.     wd_close ();
  115. }
  116.  
  117.  
  118. usage ()
  119. {
  120.     fprintf ( stderr , "Usage: initiate logfile commands [inputfile]\n" );
  121.     fprintf ( stderr , "The commands consist of a series of command characters\n" );
  122.     fprintf ( stderr , "If the first character is a 'f' then the hard disk is formatted\n" );
  123.     fprintf ( stderr , "and the map table is rebuilt from the input file\n" );
  124.     fprintf ( stderr , "If the following characters are 'r' or 'w' the entire hard disk\n" );
  125.     fprintf ( stderr , "is read or written to and any errors added to the map table\n" );
  126.     wd_close ();
  127.     exit ( 1 );
  128. }
  129.  
  130.  
  131. init_first_sector ()
  132. {
  133.     int i;
  134.     UBYTE *p;
  135.     long interleave_factor;
  136.     struct posn posn;
  137.     char buf[ 128 ];
  138.  
  139.     if ( fgets ( buf , sizeof(buf) , input ) != NULL
  140.     &&  sscanf ( buf , "%ld" , &first.cylinders ) != 1 ) {
  141.         fprintf ( stderr , "Failed to read number of cylinders\n" );
  142.         usage ();
  143.     }
  144.     if ( fgets ( buf , sizeof(buf) , input ) != NULL
  145.     &&  sscanf ( buf , "%ld" , &first.park_cylinder ) != 1 ) {
  146.         fprintf ( stderr , "Failed to read parking cylinder\n" );
  147.         usage ();
  148.     }
  149.     if ( fgets ( buf , sizeof(buf) , input ) != NULL
  150.     &&  sscanf ( buf , "%ld" , &first.heads ) != 1 ) {
  151.         fprintf ( stderr , "Failed to read number of heads (surfaces)\n" );
  152.         usage ();
  153.     }
  154.     if ( fgets ( buf , sizeof(buf) , input ) != NULL
  155.     &&  sscanf ( buf , "%ld" , &first.sectors ) != 1 ) {
  156.         fprintf ( stderr , "Failed to read number of sectors\n" );
  157.         usage ();
  158.     }
  159.     if ( fgets ( buf , sizeof(buf) , input ) != NULL
  160.     &&  sscanf ( buf , "%ld" , &interleave_factor ) != 1 ) {
  161.         fprintf ( stderr , "Failed to read interleave factor\n" );
  162.         usage ();
  163.     }
  164.  
  165.     first.magic = HD_MAGIC;
  166.     first.map_sectors = HD_MAP_SECTORS;
  167.     first.bad_sectors = 0;
  168.  
  169.     fprintf ( logfile , "%3ld cylinders\n" , first.cylinders );
  170.     fprintf ( logfile , "%3ld park cylinder\n" , first.park_cylinder );
  171.     fprintf ( logfile , "%3ld heads\n" , first.heads );
  172.     fprintf ( logfile , "%3ld sectors\n" , first.sectors );
  173.     fprintf ( logfile , "%3ld interleave factor\n" , interleave_factor );
  174.  
  175.     p = &first.pad[0];
  176.     for ( i = 0; i < sizeof ( first.pad ); i++ )
  177.         *p++ = 0x55;
  178.  
  179.     new_interleave ( interleave_factor );
  180.  
  181.     for ( i = 0; i < HD_MAP_SIZE; i++ )
  182.         first.map[i] = MAP_MARK_FREE;
  183.  
  184.     while ( fgets ( buf , sizeof(buf) , input ) != NULL ) {
  185.  
  186.         switch ( sscanf ( buf , "%ld %ld %ld\n" ,
  187.             &posn.cylinder , &posn.surface , &posn.sector ) ) {
  188.  
  189.         case 2 :
  190.             for ( posn.sector = 0; posn.sector < first.sectors; posn.sector++ ) {
  191.                 posn.block = posn.sector
  192.                     + ( posn.surface * first.sectors )
  193.                     + ( posn.cylinder * first.sectors * first.heads );
  194.                 bad_sector ( &posn , 0 , "input" );
  195.             }
  196.             break;
  197.  
  198.         case 3 :
  199.             posn.block = posn.sector
  200.                 + ( posn.surface * first.sectors )
  201.                 + ( posn.cylinder * first.sectors * first.heads );
  202.             bad_sector ( &posn , 0 , "input" );
  203.             break;
  204.  
  205.         default :
  206.             fprintf ( stderr , "Error in bad sector file\n" );
  207.             wd_close ();
  208.             exit ( 1 );
  209.         }
  210.     }
  211. }
  212.  
  213.  
  214. read_first_sector ()
  215. {
  216.     int i;
  217.     char *p;
  218.     struct posn posn;
  219.  
  220.     posn.cylinder = 0;
  221.     posn.surface = 0;
  222.     posn.sector = 0;
  223.     posn.block = 0;
  224.     p = (char*) &first;
  225.     for ( i = 0; i < HD_MAP_SECTORS; i++ ) {
  226.         if ( read_sector ( &posn , p ) != 0 ) {
  227.             fprintf ( stderr , "Read error when reading map sector %d\n" , i );
  228.             wd_close ();
  229.             exit ( 1 );
  230.         }
  231.         posn.sector++;
  232.         posn.block++;
  233.         p += HD_SECTOR;
  234.     }
  235.     if ( first.magic != HD_MAGIC ) {
  236.         fprintf ( stderr , "Incorrect magic number in bad sector map\n" );
  237.         fprintf ( stderr , "Want %08lx, Found %08lx\n" ,
  238.             (long)HD_MAGIC , (long)first.magic );
  239.         wd_close ();
  240.         exit ( 1 );
  241.     }
  242.     if ( first.map_sectors != HD_MAP_SECTORS ) {
  243.         fprintf ( stderr , "error: differing number of map sectors\n" );
  244.         fprintf ( stderr , "(program is hard coded for %d sectors, disk wants %d sectors\n" ,
  245.             HD_MAP_SECTORS , (int)first.map_sectors );
  246.         wd_close ();
  247.         exit ( 1 );
  248.     }
  249.  
  250.     fprintf ( logfile , "%3ld cylinders\n" , first.cylinders );
  251.     fprintf ( logfile , "%3ld park cylinder\n" , first.park_cylinder );
  252.     fprintf ( logfile , "%3ld heads\n" , first.heads );
  253.     fprintf ( logfile , "%3ld sectors\n" , first.sectors );
  254. }
  255.  
  256.  
  257. init_wbuf ()
  258. {
  259.     int i;
  260.  
  261.     for ( i = 0; i < HD_SECTOR; i++ )
  262.         wbuf[i] = i;
  263. }
  264.  
  265.  
  266. format_disk ()
  267. {
  268.     struct posn posn;
  269.     int status;
  270.     int i;
  271.  
  272.     for ( posn.cylinder = 0; posn.cylinder < first.cylinders; posn.cylinder++ ) {
  273.         printf ( "%03ld " , posn.cylinder );
  274.         for ( posn.surface = 0; posn.surface < first.heads; posn.surface++ ) {
  275.             posn.sector = 0;
  276.             posn.block = posn.sector
  277.                 + ( posn.surface * first.sectors )
  278.                 + ( posn.cylinder * first.sectors * first.heads );
  279.             printf ( "%ld " , posn.surface );
  280.             fflush ( stdout );
  281.  
  282.             wd_format_track ( &posn );
  283.         }
  284.         printf ( "\n" );
  285.     }
  286. }
  287.  
  288.  
  289. read_disk ( check )
  290. int check;
  291. {
  292.     struct posn posn;
  293.     int status;
  294.     int i;
  295.  
  296.     for ( posn.cylinder = 0; posn.cylinder < first.cylinders; posn.cylinder++ ) {
  297.         printf ( "%03ld " , posn.cylinder );
  298.         fflush ( stdout );
  299.         for ( posn.surface = 0; posn.surface < first.heads; posn.surface++ ) {
  300.             /*
  301.             printf ( "%03ld %ld " , posn.cylinder , posn.surface );
  302.             fflush ( stdout );
  303.             */
  304.             for ( posn.sector = 0; posn.sector < first.sectors; posn.sector++ ) {
  305.                 posn.block = posn.sector
  306.                     + ( posn.surface * first.sectors )
  307.                     + ( posn.cylinder * first.sectors * first.heads );
  308.  
  309.                 if ( is_bad ( &posn ) ) {
  310.                     /*
  311.                     putchar ( 's' );
  312.                     fflush ( stdout );
  313.                     */
  314.                     continue;
  315.                 }
  316.                 /*
  317.                 putchar ( '.' );
  318.                 fflush ( stdout );
  319.                 */
  320.  
  321.                 status = read_sector ( &posn , rbuf );
  322.                 if ( status != 0 )
  323.                     bad_sector ( &posn , status , "read" );
  324.  
  325.                 if ( check ) {
  326.                     if ( ! cmp_equal ( rbuf , wbuf ) )
  327.                         bad_sector ( &posn , 0 , "compare" );
  328.                 }
  329.             }
  330.             /*
  331.             printf ( "\n" );
  332.             */
  333.         }
  334.     }
  335. }
  336.  
  337.  
  338. write_disk ()
  339. {
  340.     struct posn posn;
  341.     int status;
  342.     int i;
  343.  
  344.     for ( posn.cylinder = 0; posn.cylinder < first.cylinders; posn.cylinder++ ) {
  345.         for ( posn.surface = 0; posn.surface < first.heads; posn.surface++ ) {
  346.             printf ( "%03ld %ld " , posn.cylinder , posn.surface );
  347.             fflush ( stdout );
  348.             for ( posn.sector = 0; posn.sector < first.sectors; posn.sector++ ) {
  349.                 posn.block = posn.sector
  350.                     + ( posn.surface * first.sectors )
  351.                     + ( posn.cylinder * first.sectors * first.heads );
  352.  
  353.                 if ( is_bad ( &posn ) ) {
  354.                     putchar ( 's' );
  355.                     fflush ( stdout );
  356.                     continue;
  357.                 }
  358.                 putchar ( '.' );
  359.                 fflush ( stdout );
  360.  
  361.                 status = write_sector ( &posn , wbuf );
  362.                 if ( status != 0 )
  363.                     bad_sector ( &posn , status , "write" );
  364.             }
  365.             printf ( "\n" );
  366.         }
  367.     }
  368. }
  369.  
  370.  
  371. bad_sector ( posn , status , msg )
  372. struct posn *posn;
  373. int status;
  374. char *msg;
  375. {
  376.     fprintf ( logfile ,
  377.         "%s: Cylinder %ld, Head %ld, Sector %ld:  Status %d\n" ,
  378.         msg , posn->cylinder , posn->surface , posn->sector , status );
  379.     printf ( "\n%s: Cylinder %ld, Head %ld, Sector %ld:  Status %d\n" ,
  380.         msg , posn->cylinder , posn->surface , posn->sector , status );
  381.  
  382.     /* ok, now add it to the table of bad sectors */
  383.  
  384.     while ( first.bad_sectors < HD_MAP_SIZE
  385.     &&  first.map[ first.bad_sectors ] == MAP_MARK_BAD )
  386.         first.bad_sectors++;
  387.  
  388.     if ( first.bad_sectors < HD_MAP_SIZE ) {
  389.         first.map[ first.bad_sectors++ ] = posn->block;
  390.     }
  391.     else {
  392.         fprintf ( logfile , "   Overflow:  Too many bad sectors!\n" );
  393.         printf ( "   Overflow:  Too many bad sectors!\n" );
  394.     }
  395.  
  396.     /* if a bad sector, mark the bad map table so dont try and replace */
  397.     /* a bad sector with a bad sector */
  398.  
  399.     if ( posn->block < HD_MAP_SECTORS ) {
  400.         printf ( "FATAL ERROR! bad sector in map table\n" );
  401.         fprintf ( logfile , "FATAL ERROR! bad sector in map table\n" );
  402.     }
  403.     else if ( posn->block < HD_MAP_SECTORS + HD_MAP_SIZE )
  404.         first.map[ posn->block - HD_MAP_SECTORS ] = MAP_MARK_BAD;
  405. }
  406.  
  407.  
  408. cmp_equal ( buf1 , buf2 )
  409. register char *buf1 , *buf2;
  410. {
  411.     register int i;
  412.  
  413.     for ( i = 0; i < HD_SECTOR; i++ )
  414.         if ( buf1[i] != buf2[i] )
  415.             return ( 0 );
  416.     return ( 1 );
  417. }
  418.  
  419.  
  420. dump_first_sector ()
  421. {
  422.     struct posn posn;
  423.     int i , j;
  424.     LONG *pl;
  425.     char *p;
  426.     int count;
  427.  
  428.     fprintf ( logfile , "\nInitial Sector\n" );
  429.     pl = (LONG*) &first;
  430.     for ( i = 0; i < sizeof(first)/sizeof(long); i++ ) {
  431.         fprintf ( logfile , "%08lx " , *pl++ );
  432.         if ( ( i + 1 ) % 8 == 0 )
  433.             fprintf ( logfile , "\n" );
  434.     }
  435.     fprintf ( logfile , "\n" );
  436.  
  437.     posn.surface = 0;
  438.     posn.cylinder = 0;
  439.     posn.sector = 0;
  440.     posn.block = 0;
  441.     p = (char*) &first;
  442.     count = HD_MAP_SECTORS;
  443.     while ( count-- > 0 ) {
  444.         if ( write_sector ( &posn , p ) != 0 )
  445.             fprintf ( stderr , "Failed to write map sector %d\n" ,
  446.                 posn.sector );
  447.         posn.sector++;
  448.         posn.block++;
  449.         p += HD_SECTOR;
  450.     }
  451. }
  452.  
  453.  
  454. is_bad ( posn )
  455. struct posn *posn;
  456. {
  457.     int i;
  458.  
  459.     for ( i = 0; i < first.bad_sectors; i++ ) {
  460.         if ( posn->block == first.map[ i ] )
  461.             return ( 1 );
  462.     }
  463.     return ( 0 );
  464. }
  465.  
  466.  
  467. new_interleave ( interleave )
  468. long interleave;
  469. {
  470.     int i;
  471.     int j;
  472.  
  473.     for ( i = 0; i < first.sectors; i++ )
  474.         first.interleave[i*2+1] = first.sectors;    /* mark as free */
  475.     j = 0;
  476.     for ( i = 0; i < first.sectors; i++ ) {
  477.         while ( first.interleave[j*2+1] != first.sectors ) {
  478.             j++;
  479.             while ( j >= first.sectors ) j -= first.sectors;
  480.         }
  481.         first.interleave[j*2+1] = i;
  482.         j += interleave;
  483.         while ( j >= first.sectors ) j -= first.sectors;
  484.     }
  485.     for ( i = 0; i < first.sectors; i++ )
  486.         printf ( "%d " , first.interleave[i*2+1] );
  487.     printf ( "\n" );
  488. }
  489.